package com.tianjian.service;

import com.tianjian.dao.IkExtWordDaoI;
import com.tianjian.dto.WordInfo;
import com.tianjian.entity.IkExtWordEntity;
import com.tianjian.exception.SelfException;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.service.spi.ServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

@Service
public class IkExtWordService {
    @Autowired
    private IkExtWordDaoI ikExtWordRepository;

    /**
     * 获取全部分词
     *
     * @return
     */
    public List<IkExtWordEntity> allWorld() {
        return ikExtWordRepository.findAll(Sort.by(Sort.Direction.DESC, "updateTime"));
    }

    public List<IkExtWordEntity> allWorld2es() {
        return ikExtWordRepository.findAll(Sort.by(Sort.Direction.DESC, "updateTime"));
    }

    /**
     * 获取分词更新状态(需要考虑更新，添加和删除情况)
     *
     * @return
     */
    public String getETag() {
        Page<IkExtWordEntity> ikExtWordPage
                = ikExtWordRepository.findAll(PageRequest.of(0, 1, Sort.by(Sort.Direction.DESC, "updateTime")));
        long total = ikExtWordPage.getTotalElements();
        long updateTime = System.currentTimeMillis();
        if (total > 0) {
            IkExtWordEntity ikExtWord = ikExtWordPage.getContent().get(0);
            updateTime = ikExtWord.getUpdateTime().toEpochSecond(ZoneOffset.of("+8"));
        }
        return updateTime + ":" + total;
    }

    /**
     * 添加分词
     *
     * @param word
     * @return
     * @throws ServiceException
     */
    @Transactional(rollbackFor = ServiceException.class)
    public IkExtWordEntity addWord(String word) {
        IkExtWordEntity ikExtWordEntity = ikExtWordRepository.findFirstByWord(word);
        if (Objects.nonNull(ikExtWordEntity)) {
            throw new SelfException("分词已存在：" + word, 500);
        }
        IkExtWordEntity brahmaTabIkExtWordEntity = new IkExtWordEntity();
        brahmaTabIkExtWordEntity.setWord(word);
        brahmaTabIkExtWordEntity.setUpdateTime(LocalDateTime.now());
        return ikExtWordRepository.save(brahmaTabIkExtWordEntity);
    }

    /**
     * 删除指定分词
     *
     * @param id
     */
    @Transactional(rollbackFor = ServiceException.class)
    public void deleteWord(Long id) {
        ikExtWordRepository.deleteById(id);
    }

    /**
     * 查询指定分词
     *
     * @param word
     * @return
     */
    public IkExtWordEntity findByWord(String word) {
        return ikExtWordRepository.findFirstByWord(word);
    }

    /**
     * 条件查询
     *
     * @param search
     * @param page
     * @param size
     * @return
     */
    public Page<IkExtWordEntity> findBySearchKey(String search, int page, int size) {
        page = page - 1;
        if (page < 0) {
            page = 0;
        }
        if (size <= 0) {
            size = 10;
        }
        Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "updateTime"));
        return ikExtWordRepository.findAll(
                (Root<IkExtWordEntity> root,
                 CriteriaQuery<?> query,
                 CriteriaBuilder criteriaBuilder) -> {
                    if (StringUtils.isNoneBlank(search)) {
                        String searchStr = "%" + search + "%";
                        Predicate result = criteriaBuilder.like(root.get("word"), searchStr);
                        query.where(result);
                    }
                    return null;
                },
                pageable);
    }

    /**
     * 更新指定分词
     *
     * @param wordEntity
     * @return
     * @throws ServiceException
     */
    @Transactional(rollbackFor = ServiceException.class)
    public IkExtWordEntity updateExtWord(IkExtWordEntity wordEntity)
            throws ServiceException {
        Long id = wordEntity.getId();
        String word = wordEntity.getWord();
        if (Objects.isNull(id)) {
            throw new ServiceException("id不能为空");
        }
        if (StringUtils.isBlank(word)) {
            throw new ServiceException("分词不能修改为空");
        }
        Optional<IkExtWordEntity> result = ikExtWordRepository.findById(id);
        if (result.isPresent()) {
            IkExtWordEntity data = result.get();
            data.setUpdateTime(LocalDateTime.now());
            data.setWord(word);
            return ikExtWordRepository.save(data);
        }
        throw new ServiceException("不存在这个id：" + id);
    }

    public Page<IkExtWordEntity> findAllByWordLike(WordInfo wordInfo) {
        // 排序条件
        Sort sort = new Sort(Sort.Direction.DESC, "updateTime");
        // 分页查询从0开始
        return ikExtWordRepository.findAllByWordLike(PageRequest.of(wordInfo.getPage() - 1, wordInfo.getRows(), sort), "%" + wordInfo.getWord() + "%");
    }
}
